//
// Created by Criinal Nicole on 2020/6/17.
//

#include "Controller.h"
#include "../IO/IO.h"
#include <iostream>
#include <string>
#include <algorithm>

using std::cout;
using std::cin;
using std::endl;
using std::string;

using SUPER_NODE::SuperNode;
using IO::WriteData;
using IO::GetData;
using USER::Admin;

int Controller::curDictionaryInode;

int Controller::lastINodeNum = 0;

int Controller::curUserId = -1;

int Controller::USER_OFFSET(int userId) {
    return sizeof(SUPER_NODE::SuperNode) +
           userId * sizeof(USER::User);
}

int Controller::DICTIONARY_OFFSET(int dictionaryId) {
    return USER_OFFSET(USER::MAX_USER_NUM) +
           dictionaryId * sizeof(DIRECTORY_BLOCK::DirectoryBlock);
}

int Controller::FILE_OFFSET(int fileId) {
    return DICTIONARY_OFFSET(DIRECTORY_BLOCK::MAX_DIRECTORY_NUM) +
           fileId * sizeof(FILE_INDEX_NODE::FileIndexNode);
}

int Controller::BLOCK_OFFSET(int blockId) {
    return FILE_OFFSET(FILE_INDEX_NODE::MAX_FILE_INDEX_NUM) +
           blockId * sizeof(BLOCK::Block);
}

void Controller::initialize() {
    int token;
    IO::GetData(0, token);
    if (token != 2020) {
        cout << "检测到系统异常，正在格式化中……\n";
        format();
    } else {
        GetData(0, SuperNode);
        for (int i = 0; i < USER::MAX_USER_NUM; ++i) {
            GetData(USER_OFFSET(i), USER::Users[i]);
        }
        for (int i = 0; i < DIRECTORY_BLOCK::MAX_DIRECTORY_NUM; ++i) {
            GetData(DICTIONARY_OFFSET(i),
                    DIRECTORY_BLOCK::dictionaryBlocks[i]);
        }
        for (int i = 0; i < FILE_INDEX_NODE::MAX_FILE_INDEX_NUM; ++i) {
            IO::GetData(Controller::FILE_OFFSET(i), FILE_INDEX_NODE::fileIndexNodes[i]);
        }
        for (int i = 0; i < BLOCK::MAX_BLOCK_NUM; ++i) {
            GetData(BLOCK_OFFSET(i), BLOCK::blocks[i]);
        }
    }
    curDictionaryInode = 0;
//    将最后一个被占用i节点的后继节点设置成MAX_FILE_INDEX_NUM
    getLastINodeNum(0);
    FILE_INDEX_NODE::fileIndexNodes[lastINodeNum]._posInDictionaryBlock = FILE_INDEX_NODE::MAX_FILE_INDEX_NUM;
    USER::currentUserNumber = 0;
    while (USER::Users[USER::currentUserNumber]._privilege != 0)USER::currentUserNumber++;
}


void Controller::format() {
    SUPER_NODE::init();
    USER::init();
    DIRECTORY_BLOCK::init();
    FILE_INDEX_NODE::init();
    BLOCK::init();
    store();
}

void Controller::getLastINodeNum(int iNodeNum) {
    auto &iNode = FILE_INDEX_NODE::fileIndexNodes[iNodeNum];
    if (iNode._posInDictionaryBlock != -1) {
        lastINodeNum = std::max(iNodeNum, lastINodeNum);
        for (int i = 0; i < iNode._blockNum; ++i) {
            getLastINodeNum(iNode._blockId[i]);
        }
    }
}

void Controller::store() {
//        如果不存在，则创建
    std::fstream f_in(IO::_fileName, std::ios::binary | std::ios::out);
    f_in.close();
    std::ofstream f_out(IO::_fileName, std::ios::binary
                                       | std::ios::in);
    f_out.seekp(0, std::ios::beg);
    f_out.write((char *) &SUPER_NODE::SuperNode, sizeof(SuperNode));

    for (auto &i : USER::Users) {
        f_out.write((char *) &i, sizeof(i));
    }
    for (auto &i : DIRECTORY_BLOCK::dictionaryBlocks) {
        f_out.write((char *) &i, sizeof(i));
    }
    for (auto &i : FILE_INDEX_NODE::fileIndexNodes) {
        f_out.write((char *) &i, sizeof(i));
    }
    for (auto &i : BLOCK::blocks) {
        f_out.write((char *) &i, sizeof(i));
    }
    f_out.close();
}



